package com.fangsheng.zookeeper.config;

import org.apache.zookeeper.AsyncCallback;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

import java.util.concurrent.CountDownLatch;

/**
 * @创建人: 放生
 * @创建时间: 2021/11/3
 * @描述: WatchCallBack 既是 watch 又是callBack
 */
public class WatchCallBack implements Watcher, AsyncCallback.StatCallback, AsyncCallback.DataCallback{

    ZooKeeper zk ;
    MyConf conf ;
    CountDownLatch cc = new CountDownLatch(1);

    public MyConf getConf() {
        return conf;
    }

    public void setConf(MyConf conf) {
        this.conf = conf;
    }

    public ZooKeeper getZk() {
        return zk;
    }

    public void setZk(ZooKeeper zk) {
        this.zk = zk;
    }


    public void aWait(){
        // 这不步是异步
        zk.exists("/AppConf",this,this ,"ABC");
        try {
            // 所以需要阻塞住，如果一进来没有这个目录会被阻塞住
            cc.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    // 这个方法是  AsyncCallback.DataCallback 只要zk.getData（）方法执行就会触发这个方法
    @Override
    public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {

        if(data != null ){
            String s = new String(data);
            conf.setConf(s);
            cc.countDown();
        }


    }
    // 这个方法是 AsyncCallback.StatCallback,
    @Override
    public void processResult(int rc, String path, Object ctx, Stat stat) {
        if(stat != null){
            zk.getData("/AppConf",this,this,"sdfs");
        }

    }

    // 这个方法是watch 的 只要你有人创建了这个 /AppConf 并且放入了数据就会触发下面的getData 方法
    @Override
    public void process(WatchedEvent event) {

        switch (event.getType()) {
            case None:
                break;
            case NodeCreated: // 节点创建时触发
                zk.getData("/AppConf",this,this,"sdfs");

                break;
            case NodeDeleted: // 节点被删除
                //容忍性
                conf.setConf("");
                cc = new CountDownLatch(1);
                break;
            case NodeDataChanged: // 节点改变时候触发
                zk.getData("/AppConf",this,this,"sdfs");

                break;
            case NodeChildrenChanged:
                break;
        }

    }



}
